home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-13
/
dbasedt3.zip
/
DBASEDIT.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-01-04
|
39KB
|
1,677 lines
PAGE 80,132
TITLE DBASEDIT Editor for text entry in dBASE III
; .BIN program to use a window inside the dBASE program to create or
; modify a text file. Used by LOADing the program under dBASE then
; CALLing it with a parameter list. The parameter list is generated
; in dBASE as a concatenated text string. There are 5 3 byte ASCII
; strings with the folowing parameters, in order:
; first row of the edit window
; last row of the edit window
; first column of the edit window
; last column of the edit window
; max number of lines for the data
; They are followed by the 12 byte file name (includes extension) and
; one character which should be a Y or N and indicates to DBASEDIT
; whether data will be input (Y) or just displayed in the window (N).
;
; Assemble the source (this version used the Microsoft Macro Assembler
; Version 5.0), then LINK and EXE2BIN.
;
; Following is a sample segment of dBASE source code to use DBASEDIT:
;
COMMENT ^ ...Set up code goes here
LOAD DBASEDIT
...
FIRSTROW = 2
FIRSTCOL = 1
LASTROW = 23
LASTCOL = 78
MAXLINES = 44
FILENAM = 'HELPXXXX.TXT'
DOANS = 'Y'
PARM = STR(FIRSTROW,3) + STR(LASTROW,3) + STR(FIRSTCOL,3) + ;
STR(LASTCOL,3) + STR(MAXLINES,3) + FILENAM + DOANS
@ FIRSTROW-1,FIRSTCOL-1 TO LASTROW+1,LASTCOL+1 DOUBLE
IF ISCOLOR()
SET COLOR TO W+/R
ENDIF
@ FIRSTROW,FIRSTCOL CLEAR TO LASTROW,LASTCOL
@ LASTROW+1,18 SAY '[ Press F1 for Editor Help/ F10 when done. ]'
CALL DBASEDIT WITH PARM
RELEASE DBASEDIT
.... other processing follows ^
;
; The above code would look for the file HELPTEMP.TXT and move the
; data from it to the screen if it is found. At the end of editting,
; a file by that name would be created. I created the file from a
; dBASE data base then restore the original data base by appending
; from the created file. It works well and allows some word processor
; type editting on a dBASE screen. Look at the code or use the routine
; and press F1 to find out which keys are used and what their functions
; are.
; Macros
.SALL
PUSHALL MACRO
PUSHF
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH BP
PUSH DS
PUSH ES
PUSH SS
ENDM
POPALL MACRO
POP SS
POP ES
POP DS
POP BP
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
POPF
ENDM
GCRSR MACRO
;; Gets the current cursor column,row position in DL,DH.
PUSH AX
PUSH BX
PUSH CX
XOR BX,BX ;;set for page 0
MOV AH,03H ;;function code
INT 010H
POP CX
POP BX
POP AX
ENDM
SCRSR MACRO
;; Sets cursor to column,row position in DL,DH
PUSH AX
PUSH BX
XOR BX,BX
MOV AH,02H
INT 010H
POP BX
POP AX
ENDM
WCRSR MACRO
;; Writes the character in AL at the current cursor location
PUSH AX
PUSH BX
PUSH CX
XOR BX,BX
MOV CX,1
MOV AH,0AH
INT 010H
POP CX
POP BX
POP AX
ENDM
WCRSR2 MACRO
;; Writes the character in AL at the current cursor location
PUSH AX
PUSH BX
XOR BX,BX
MOV AH,0EH
INT 010H
POP BX
POP AX
ENDM
CSEG SEGMENT BYTE
ASSUME CS:CSEG,DS:CSEG,ES:CSEG
ORG 0H
PUBLIC DBASEDIT
DBASEDIT PROC FAR
JMP EDITEXT
NUL EQU 0
BEL EQU 07H
CR EQU 0DH
LF EQU 0AH
EOF EQU 01AH
EOL EQU '$'
LINELEN EQU 75 ;default line length
MAXLEN EQU LINELEN * 100 ;default max buffer size
THREE_BLANKS DB ' '
INS_STRING DB 'Ins'
FILENAME DB 'DBASEDIT.TXT',NUL
ERR1 DB CR,LF,'Requested space exceeds maximum allowed. Will use max of 7500 bytes.',EOL
ERR2 DB CR,LF,"Can't create work file. Check disk space available. Must exit.",EOL
; HELP text and JMP tables listings suppressed
.XLIST
HELP_TEXT DB ' AADS Editor Help Screen',CR,LF
L2 DB ' Key Function',CR,LF
L3 DB ' F1 Invokes this Help screen.',CR,LF
L4 DB ' F3 Inserts a line at the cursor position.',CR,LF
L5 DB ' F5 Deletes the line at the cursor position.',CR,LF
L6 DB ' F7 Deletes from the cursor to end of text.',CR,LF
L7 DB ' F10 Ends the Editor session and resumes AADS processing.',CR,LF
L8 DB ' Tab Moves cursor to next tab position. (Tabs are set 8 spaces apart.)',CR,LF
L9 DB ' Home Moves cursor to beginning of current line.',CR,LF
L10 DB ' End Moves cursor to end of current line.',CR,LF
L11 DB ' Ctrl/End Clears text to end of line.',CR,LF
L12 DB ' PgUp Scrolls the window to the previous page. Shows first line of ',CR,LF
L13 DB ' text if scroll is at or past top.',CR,LF
L14 DB ' Ctrl/PgUp Moves to beginning of first window of text.',CR,LF
L15 DB ' PgDn Scrolls the window to the next full page. Stops at last line of',CR,LF
L16 DB ' text if scroll is at or past bottom.',CR,LF
L17 DB ' Ctrl/PgDn Moves to beginning of last window of text.',CR,LF
L18 DB ' Backspace Deletes the charcter ahead of the cursor and moves all following',CR,LF
L19 DB ' characters forward one space.',CR,LF
L20 DB ' Del Same as Backspace but deletes character under cursor.',CR,LF
L21 DB ' Ins Puts Editor in Insert mode. Operates just like dBASE.',CR,LF
L22 DB ' Cursor Keys Move the cursor through the text without changing it.',CR,LF
L23 DB CR,LF
L24 DB '* NOTE - Undefined keys or keys at their limits will beep.',CR,LF,EOL
L25 DB CR,LF
.LIST
IN_FIELD DB '011021003077020EDITXT.TXT Y' ;defaults
DB NUL,EOL
ARGUMENT DB 3 DUP(0)
DB 0
CR_LF DB CR,LF
END_OF_FILE DB EOF
HOLD_CHAR DB 0
HCURSOR_SAVE DB 0
INSERT_TOGGLE DB 0
FIRST_ROW DB 13
LAST_ROW DB 22
FIRST_COLUMN DB 3
DB 0
ORG $-2
FIRST_COL_WORD DW ?
EXEC_FLAG DB ' '
LAST_COLUMN DB 77
ATTRIBUTE DB 0
INSERT_STATUS DB 0
LINE_BUFFER DB 80 DUP(0) ;for existing file input
HELP_SW DB 0
IN_LAST_PAGE DB 0
SKIP_FLAG DW 0 ;cancels scroll in ADVANCE_CURSOR
IN_LINE_COUNT DW 0
FIELD_LENGTH DW MAXLEN ;start at max
HANDLE DW 0
PGWIDTH DW 0
WINDOW_LINES DW 0 ;number of lines in window
SCROLL_PAGE DW 0 ;page we're now in
PAGE_SIZE DW 0 ;number of characters in a page
BUFFER_END DW 0 ;address of end of buffer
BUFFER_LEFT DW 0 ;holds number of remaining chars
BUFFER_POSITION DW 0 ;holds character position
LINE_POSITION DW 1 ;holds number of chars on line so far
INPUT_SIZE DW 0 ;holds size of input text
OUTPUT_LINES DW 0
REG4 DW 0
REG5 DW 0
REG8 DW 0
;
; Keyboard Function Codes Tables
FUNCTAB STRUC
FUNCCODE DB 00H
FUNCADDR DW 0000H
FUNCTAB ENDS
.XLIST
; Function Codes
; Regular keyboard characters
XTNCHR EQU 00
XITCHR EQU 03 ;exit to system (^C or CtrlBrk)
BAKCHR EQU 08 ;destructive back space
TABCHR EQU 09 ;forward tab
LFDCHR EQU 10 ;line feed/new line
RETCHR EQU 13 ;carriage return
EOFCHR EQU 26 ;end of file character
ESCCHR EQU 27 ;ESC character
; Extended Function Codes
F1CHR EQU 59 ;F1 key
F2CHR EQU 60 ;F2 key
F3CHR EQU 61
F4CHR EQU 62
F5CHR EQU 63
F6CHR EQU 64
F7CHR EQU 65
F8CHR EQU 66
F9CHR EQU 67
F10CHR EQU 68
HMECHR EQU 71
UPCCHR EQU 72 ;up cursor
PAGEUP EQU 73 ;page up
LFTCUR EQU 75 ;cursor left
RHTCUR EQU 77 ;cursor right
ENDCHR EQU 79 ;END
DWNCHR EQU 80 ;down cursor
PAGEDN EQU 81 ;page down
INSCHR EQU 82 ;INS
DELCHR EQU 83 ;DEL
CLREOL EQU 117 ;Ctrl/End
ENDSCN EQU 118 ;Ctrl/PgDn
TOP EQU 132 ;Ctrl/PgUp
; Function Table
REG_KEYS:
FUNCTAB <RETCHR,DO_RETURN>
FUNCTAB <XTNCHR,XTN_CHK> ;extended ASCII coming
FUNCTAB <TABCHR,DO_TAB>
FUNCTAB <BAKCHR,BACK_SPACE>
FUNCTAB <EOFCHR,DO_END> ;same as END
FUNCTAB <XITCHR,DO_BREAK> ;control break
FUNCTAB <LFDCHR,DO_RETURN>
FUNCTAB <ESCCHR,DO_ESCAPE>
REG_KEYS_ENTS EQU ($-REG_KEYS)/TYPE FUNCTAB
EXTN_KEYS:
FUNCTAB <F1CHR,HELP>
FUNCTAB <F2CHR,BAD_KEY>
FUNCTAB <F3CHR,INSERT_LINE>
FUNCTAB <F4CHR,BAD_KEY>
FUNCTAB <F5CHR,DELETE_LINE>
FUNCTAB <F6CHR,BAD_KEY>
FUNCTAB <F7CHR,DELETE_TO_EOT>
FUNCTAB <F8CHR,BAD_KEY>
FUNCTAB <F9CHR,BAD_KEY>
FUNCTAB <F10CHR,GET_LINE_END>
FUNCTAB <INSCHR,INSERT>
FUNCTAB <DELCHR,DELETE_CHAR>
FUNCTAB <ENDCHR,DO_END>
FUNCTAB <LFTCUR,CURSOR_LEFT>
FUNCTAB <RHTCUR,CURSOR_RT>
FUNCTAB <HMECHR,HOME_KEY>
FUNCTAB <UPCCHR,CURSOR_UP>
FUNCTAB <PAGEUP,DO_PAGE_UP>
FUNCTAB <DWNCHR,CURSOR_DOWN>
FUNCTAB <PAGEDN,DO_PAGE_DOWN>
FUNCTAB <XITCHR,DO_BREAK>
FUNCTAB <CLREOL,CLEAR_TO_EOL>
FUNCTAB <TOP,START_SCREEN>
FUNCTAB <ENDSCN,END_SCREEN>
EXTN_KEYS_ENTS EQU ($-EXTN_KEYS)/TYPE FUNCTAB
; End of tables
.LIST
SUBTTL Program Code
PAGE
EDITEXT PROC NEAR
PUSHALL
MOV AX,CS
MOV ES,AX
MOV DI,Offset IN_FIELD
MOV SI,BX
MOV CX,28
REP MOVSB
PUSH ES
POP DS
MOV BX,Offset SCRN_BUFR_END ;calculate program size
SUB BX,Offset DBASEDIT
MOV CL,4
SHR BX,CL ;make into paragraphs
ADD BX,100H ;handle excess
MOV AH,04AH ;modify memory function
INT 021H ;shrink memory to program size
CLD ;scan is up
MOV AH,02H ;check INS key status
INT 016H
MOV INSERT_STATUS,AL ;save it
TEST AL,10000000B ;bit 7 on?
JZ INSERT_OFF
MOV INSERT_TOGGLE,0FFH ;set toggle
JMP Short EDIT_TXT_0
INSERT_OFF:
MOV INSERT_TOGGLE,0 ;turn toggle off
EDIT_TXT_0:
CALL SHOW_INSERT ;put Ins on screen
MOV HELP_SW,0 ;HELP has not been called
MOV CX,3 ;convert input parameters
MOV SI,Offset IN_FIELD
MOV DI,Offset ARGUMENT
REP MOVSB
CALL CNVT_DEC ;this converts input to hex in CX
MOV FIRST_ROW,CL
MOV CX,3 ;convert input parameters
MOV SI,Offset IN_FIELD+3
MOV DI,Offset ARGUMENT
REP MOVSB
CALL CNVT_DEC ;this converts input to hex in CX
MOV LAST_ROW,CL
MOV CX,3 ;convert input parameters
MOV SI,Offset IN_FIELD+6
MOV DI,Offset ARGUMENT
REP MOVSB
CALL CNVT_DEC ;this converts input to hex in CX
MOV FIRST_COLUMN,CL
MOV CX,3 ;convert input parameters
MOV SI,Offset IN_FIELD+9
MOV DI,Offset ARGUMENT
REP MOVSB
CALL CNVT_DEC ;this converts input to hex in CX
MOV LAST_COLUMN,CL
MOV CX,3 ;convert input parameters
MOV SI,Offset IN_FIELD+12
MOV DI,Offset ARGUMENT
REP MOVSB
CALL CNVT_DEC ;this converts input to hex in CX
MOV IN_LINE_COUNT,CX ;save for loop counts
MOV CX,12 ;get file name input parameter
MOV SI,Offset IN_FIELD+15
MOV DI,Offset FILENAME
REP MOVSB
MOV CX,12
INP_LINE_1:
DEC DI
CMP Byte Ptr 0[DI],' '
JNE INP_LINE_2
MOV Byte Ptr 0[DI],0 ;make ASCIIZ
LOOP INP_LINE_1
INP_LINE_2:
MOV CX,1 ;get last input parameter
MOV SI,Offset IN_FIELD+27
MOV DI,Offset EXEC_FLAG
REP MOVSB
XOR AX,AX
MOV AL,LAST_COLUMN
SUB AL,FIRST_COLUMN
INC AX ;now has width of line
MOV PGWIDTH,AX
XOR AX,AX ;calculate number of lines in window
MOV AL,LAST_ROW
SUB AL,FIRST_ROW
INC AX
MOV WINDOW_LINES,AX
MOV BX,PGWIDTH
MUL BX
MOV PAGE_SIZE,AX
MOV AX,Offset SCRN_BUFR
MOV BUFFER_POSITION,AX ;set screen position
MOV AX,PGWIDTH
MOV BX,IN_LINE_COUNT
MUL BX
MOV BUFFER_LEFT,AX ;initialize # of remaining characters
MOV FIELD_LENGTH,AX ;and save it
ADD AX,BUFFER_POSITION ;find end of buffer + 1
MOV BUFFER_END,AX
CMP AX,Offset SCRN_BUFR_END
JLE EDITXT_1
MOV DX,Offset ERR1
MOV AH,09H
INT 021H
CALL BEEP
MOV AH,08H
INT 021H
MOV AX,MAXLEN
MOV BUFFER_LEFT,AX ;initialize # of remaining characters
MOV FIELD_LENGTH,AX ;and save it
ADD AX,BUFFER_POSITION ;find end of buffer + 1
MOV BUFFER_END,AX
EDITXT_1:
MOV LINE_POSITION,1 ;initialize at start
MOV DI,Offset SCRN_BUFR ;clear the buffer
MOV CX,BUFFER_LEFT
MOV AL,' '
REP STOSB
; ;read existing data
MOV DX,Offset FILENAME
MOV AX,03D00H
INT 021H
JC EDITXT_6 ;no file, nothing to load
MOV HANDLE,AX ;found, save it
MOV BX,AX ;and set for read
PUSH ES
PUSH DS
POP ES
MOV DI,Offset SCRN_BUFR
EDITXT_2:
MOV CX,PGWIDTH ;read record + <CR><LF>
INC CX
INC CX
MOV DX,Offset LINE_BUFFER
MOV AH,03FH
INT 021H
CMP AX,0
JE EDITXT_5 ;all done, close
MOV SI,Offset LINE_BUFFER
CMP Byte Ptr 0[SI],EOF ;end of file?
JE EDITXT_5 ;yes, also done
EDITXT_3:
LODSB ;get the char
CMP AL,' ' ;valid text character?
JL EDITXT_4 ;no, bypass
STOSB ;store the data in the screen buffer
EDITXT_4:
LOOP EDITXT_3 ;keep storing
JMP EDITXT_2
EDITXT_5:
MOV AH,03EH ;close the file
INT 021H
POP ES ;restore
EDITXT_6:
MOV DH,FIRST_ROW ;put cursor on window
MOV DL,FIRST_COLUMN
SCRSR
MOV AH,08H ;now find the attribute
INT 010H
MOV ATTRIBUTE,AH ;save it
XOR BX,BX ;clear
MOV BH,AH ;attribute to fill with
MOV AH,06H
MOV AL,00H ;initialize window
MOV CH,FIRST_ROW
MOV CL,FIRST_COLUMN
MOV DH,LAST_ROW
MOV DL,LAST_COLUMN
INT 010H
MOV DX,CX ;put cursor at start
SCRSR
CALL MOVE_SCREEN ;fill window with data if any
CMP EXEC_FLAG,'Y' ;execute now?
JNE DBASEDIT_END ;no, go return
EDITXT_7:
CALL GET_LINE ;get a line of input
JMP EDITXT_7
EDITEXT ENDP
DBASEDIT_END PROC FAR
; Close out routine to return to dBASE program
MOV AL,INSERT_STATUS
TEST AL,10000000B ;was Ins on?
JZ EDIT_TXT_END_1 ;no
MOV INSERT_TOGGLE,0FFH
JMP Short EDIT_TXT_END_2
EDIT_TXT_END_1:
MOV INSERT_TOGGLE,0
EDIT_TXT_END_2:
CALL SHOW_INSERT
PUSH ES
MOV AX,040H
MOV ES,AX ;point at BIOS data
MOV AL,INSERT_STATUS
MOV ES:[017H],AL
POP ES
POPALL
RET ;back to dBASE III
DBASEDIT_END ENDP
GET_LINE PROC NEAR
;
MOV AX,IN_LINE_COUNT ;number of lines
MOV BX,PGWIDTH
MUL BX
MOV INPUT_SIZE,AX ;number of chars to input
MOV CX,AX
GET_LINE_LOOP1:
PUSH CX
MOV AH,07H ;get char function
INT 021H
MOV BX,Offset REG_KEYS
MOV CX,REG_KEYS_ENTS ;number of entries
REG_LOOP:
CMP AL,[BX].FUNCCODE ;is this the character?
JE FOUND_REG ;yes
ADD BX,TYPE FUNCTAB ;bump pointer
LOOP REG_LOOP
JMP Short REG_CHAR
FOUND_REG:
MOV AX,DS
PUSH CS
POP SI
SUB AX,SI
MOV CX,4
SHL AX,CL
MOV BX,[BX].FUNCADDR
ADD BX,AX
JMP BX ;process the function
POP CX
JMP GET_LINE_LOOP1
XTN_CHK: ;check extended character
MOV DL,0FFH
MOV AH,06H ;direct I/O
INT 021H
JNZ XTN_GOT_KEY ;got a key
JMP BAD_KEY
XTN_GOT_KEY:
MOV HOLD_CHAR,AL
MOV BX,Offset EXTN_KEYS
MOV CX,EXTN_KEYS_ENTS
XTN_LOOP:
CMP AL,[BX].FUNCCODE
JE FOUND_XTN
ADD BX,TYPE FUNCTAB
LOOP XTN_LOOP
JMP BAD_KEY
FOUND_XTN:
MOV AX,DS
PUSH CS
POP SI
SUB AX,SI
MOV CX,4
SHL AX,CL
MOV BX,[BX].FUNCADDR
ADD BX,AX
JMP BX ;process the function
POP CX
JMP GET_LINE_LOOP1
REG_CHAR:
CMP BUFFER_LEFT,0 ;is there room?
JNE REG_CHAR1
JMP BAD_KEY
REG_CHAR1:
CMP INSERT_TOGGLE,0FFH ;insert on?
JNE REG_CHAR1_0
MOV SI,BUFFER_END ;insert mode processing
DEC SI ;point at last character
MOV DI,SI ;and next to last
DEC SI
MOV CX,BUFFER_LEFT ;number to move
STD
REP MOVSB
CLD
MOV Byte Ptr 1[DI],' ' ;blank out current character
PUSH AX
CALL MOVE_SCREEN
POP AX
REG_CHAR1_0:
MOV BX,BUFFER_POSITION ;get buffer address
MOV Byte Ptr 0[BX],AL ;put character there
WCRSR ;display the character
DEC BUFFER_LEFT ;decrement remaining char count
JZ REG_CHAR_END ;no more space, done
INC LINE_POSITION ;bump char count
INC BUFFER_POSITION ;bump buffer address
MOV AX,BUFFER_POSITION
CMP AX,BUFFER_END ;at end?
JGE REG_CHAR_END ;yes
MOV BX,PGWIDTH
CMP BX,LINE_POSITION ;at end?
JGE REG_CHAR_0_A ;no
MOV LINE_POSITION,1
REG_CHAR_0_A:
CALL ADVANCE_CURSOR ;move cursor right
JNC REG_CHAR_1
MOV LINE_POSITION,1
CALL SCROLL_DOWN
MOV BX,BUFFER_END
CMP BX,PAGE_SIZE
JG REG_CHAR_1
MOV IN_LAST_PAGE,0FFH ;set last page switch on
REG_CHAR_1:
POP CX
DEC CX
JCXZ REG_CHAR_END ;can't use LOOP; too far
JMP GET_LINE_LOOP1
REG_CHAR_END:
CALL SET_LAST_LINE
JMP BAD_KEY
GET_LINE ENDP
GET_LINE_END PROC NEAR
POP CX ;clear stack
STD ;search from end of buffer
MOV AL,' ' ;char to look at
MOV CX,FIELD_LENGTH ;length to scan
MOV DI,BUFFER_END
DEC DI
REPZ SCASB ;look for first non blank
CLD ;restore
MOV AX,CX ;points at last character
XOR DX,DX
MOV BX,PGWIDTH
DIV BX
INC AX
MOV OUTPUT_LINES,AX ;number of lines to output
MOV AH,03CH ;create a file
MOV DX,Offset FILENAME
XOR CX,CX
INT 021H
JNC GET_LINE_END_1
PUSH AX ;save error code
MOV DX,Offset ERR2
MOV AH,09H
INT 021H
MOV AH,08H
INT 021H
POP AX ;restore error
JMP Short GET_LINE_END_RET
GET_LINE_END_1:
MOV HANDLE,AX
MOV BX,AX
MOV DX,Offset SCRN_BUFR ;set start
MOV CX,OUTPUT_LINES ;get count
GET_LINE_END_2:
PUSH CX
MOV CX,PGWIDTH
MOV AH,040H
INT 021H ;output a record
ADD DX,PGWIDTH ;bump buffer pointer
PUSH DX ;save it
MOV CX,2
MOV DX,Offset CR_LF
MOV AH,040H
INT 021H ;write a <CR><LF>
POP DX ;restore buffer pointer
POP CX ;and count
LOOP GET_LINE_END_2
MOV DX,Offset END_OF_FILE
MOV CX,1
MOV AH,040H
INT 021H
MOV BX,HANDLE
MOV AH,03EH
INT 021H
GET_LINE_END_RET:
POP AX ;clear RET
JMP Near Ptr DBASEDIT_END
GET_LINE_END ENDP
SUBTTL Key Handling Routines
PAGE
BACK_SPACE PROC NEAR
CALL CUR_LFT ;move cursor and pointers back one
JC BACK_SPACE_ERR ;can't do
MOV DI,BUFFER_POSITION ;set current location
MOV CX,BUFFER_LEFT ;set up move
DEC CX
MOV SI,DI
CMP INSERT_TOGGLE,0FFH ;in insert mode?
JNE BACK_SPACE_2 ;yes, need to collapse data
INC SI ;collapse data by one
CLD
REP MOVSB
MOV Byte Ptr 0[DI],' '
JMP BACK_SPACE_3
BACK_SPACE_2:
MOV Byte Ptr 0[DI],' '
BACK_SPACE_3:
CALL MOVE_SCREEN
JC BACK_SPACE_ERR ;just in case
POP CX ;normal return
RET
BACK_SPACE_ERR:
JMP BAD_KEY
BACK_SPACE ENDP
BAD_KEY PROC NEAR
CALL BEEP
POP CX
RET
BAD_KEY ENDP
CLEAR_TO_EOL PROC NEAR
MOV DI,BUFFER_POSITION ;point at buffer position
MOV CX,PGWIDTH
SUB CX,LINE_POSITION ;number of chars to clear
PUSH CX ;save it
GCRSR ;save current cursor
PUSH DX
MOV AL,' '
CLR_EOL_1:
WCRSR2
LOOP CLR_EOL_1
POP DX ;restore cursor
SCRSR
POP CX ;get chars to clear count
MOV AL,' '
REP STOSB
POP CX
RET
CLEAR_TO_EOL ENDP
CURSOR_DOWN PROC NEAR
MOV AX,BUFFER_POSITION ;calculate buffer change
ADD AX,PGWIDTH ;bump one line
CMP AX,BUFFER_END ;will it put us past end?
JL CURSOR_DN_1 ;no, OK to continue
JMP BAD_KEY ;go beep
CURSOR_DN_1:
MOV BX,PGWIDTH
ADD BUFFER_POSITION,BX ;set line position count
SUB BUFFER_LEFT,BX ;change chars left count
GCRSR ;get cursor location
CMP LAST_ROW,DH
JG CURSOR_DN_2
CALL SCROLL_DOWN
JMP Short CURSOR_DN_RET
CURSOR_DN_2:
INC DH ;bump to next line
SCRSR ;set cursor function
CURSOR_DN_RET:
POP CX
RET
CURSOR_DOWN ENDP
CURSOR_LEFT PROC NEAR
; Handles Left Arrow key
MOV AX,BUFFER_POSITION ;get current buffer position
CMP AX,Offset SCRN_BUFR ;at beginning?
JG CURSR_LFT_2 ;no, OK to continue
JMP BAD_KEY
CURSR_LFT_2:
GCRSR ;get current position
CMP DH,FIRST_ROW ;at top of window?
JNE CURSR_LFT_3 ;no
CMP DL,FIRST_COLUMN ;at first column?
JNE CURSR_LFT_3 ;no, move will be OK
MOV AX,PGWIDTH ;yes, set buffer position
SUB BUFFER_POSITION,AX ;to scroll up 1 line
ADD BUFFER_LEFT,AX ;this sets buffer positions for move
MOV IN_LAST_PAGE,0 ;reset flag
CALL MOVE_SCREEN ;show the moved screen
INC DH ;put cursor at same character
SCRSR
CALL BACK_CURSOR ;now move it back
MOV AX,PGWIDTH ;position for end of line
MOV LINE_POSITION,AX
DEC AX ;now set buffer position 1 space back
ADD BUFFER_POSITION,AX ;and bump pointers to line end
SUB BUFFER_LEFT,AX
JMP Short CURSR_LFT_RET
CURSR_LFT_3:
CMP BUFFER_LEFT,1 ;on last position?
JNE CURSR_LFT_4 ;no, regular case
INC LINE_POSITION ;special case so following code works
CURSR_LFT_4:
CALL CUR_LFT ;make move
JC CURSOR_LEFT_ERR ;beep if error
CURSR_LFT_RET:
POP CX
RET
CURSOR_LEFT_ERR:
JMP BAD_KEY
CURSOR_LEFT ENDP
; Moves cursor right on screen and updates buffer pointers
;
CURSOR_RT PROC NEAR
CMP BUFFER_LEFT,1 ;past or at right end?
JNG CUR_RHT_BAD ;yes, set error flag
DEC BUFFER_LEFT ;no, decrease # of chars left
INC BUFFER_POSITION ;bump char position
MOV BX,LINE_POSITION
CMP BX,PGWIDTH ;at end of line?
JL CUR_RHT_0
MOV LINE_POSITION,1 ;yes, reset position
CUR_RHT_0:
INC LINE_POSITION
CALL ADVANCE_CURSOR
JNC CUR_RHT_1 ;not at end of page
MOV LINE_POSITION,1 ;point line offset at start
CALL SCROLL_DOWN
CUR_RHT_1:
POP CX
RET
CUR_RHT_BAD:
CALL SET_LAST_LINE
JMP BAD_KEY
CURSOR_RT ENDP
CURSOR_UP PROC NEAR
GCRSR ;get current cursor position
CMP DH,FIRST_ROW ;at first row
JNE CUR_UP_2 ;no, no need to check
MOV IN_LAST_PAGE,0 ;yes, reset
MOV AX,Offset SCRN_BUFR ;check for first screen
ADD AX,PGWIDTH ;points to start of line 2 in buffer
CMP BUFFER_POSITION,AX ;is current pointer in that line?
JNL CUR_UP_1 ;no, OK to scroll up
JMP BAD_KEY
CUR_UP_1:
MOV BX,PGWIDTH ;change buffer pointers
SUB BUFFER_POSITION,BX ;by width of screen
ADD BUFFER_LEFT,BX
PUSH BUFFER_POSITION ;save position
MOV AX,LINE_POSITION
DEC AX ;adjust for base 0
SUB BUFFER_POSITION,AX ;point at start of line
GCRSR ;save current cursor position
PUSH DX
MOV DL,FIRST_COLUMN ;point cursor at start of line
SCRSR
CALL MOVE_SCREEN ;now move the screen up
POP DX ;restore cursor
SCRSR
POP BUFFER_POSITION ;restore buffer position
JMP Short CUR_UP_RET
CUR_UP_2:
DEC DH
SCRSR ;set the cursor there
MOV AX,PGWIDTH
SUB BUFFER_POSITION,AX
ADD BUFFER_LEFT,AX ;bump buffer pointers
CUR_UP_RET:
POP CX
RET
CURSOR_UP ENDP
DELETE_CHAR PROC NEAR
MOV CX,BUFFER_LEFT ;get remaining chars
DEC CX ;adjust count
MOV DI,BUFFER_POSITION ;get current address
MOV SI,DI ;copy
INC SI ;and back up one
CLD ;make sure it's forward
REP MOVSB
MOV Byte Ptr 0[DI],' ' ;blank last character position
CALL MOVE_SCREEN ;now display the new window
POP CX
RET
DELETE_CHAR ENDP
DELETE_LINE PROC NEAR
CALL FIND_LINE_NUMBER ;AX returns line number
MOV BX,PGWIDTH
MUL BX ;AX now has number of chars from start
PUSH AX ;save it
MOV CX,FIELD_LENGTH
SUB CX,AX
MOV DI,Offset SCRN_BUFR ;set up end of buffer
POP AX
PUSH AX ;keep it on hold
ADD DI,AX ;start of move
MOV SI,DI
ADD SI,PGWIDTH ;from start of next line
REP MOVSB ;do the move
MOV DI,SI ;set for blanking
MOV CX,PGWIDTH
MOV AL,' ' ;fill character
REP STOSB ;fill last line
GCRSR
MOV DL,FIRST_COLUMN
SCRSR
POP AX ;get offset from start
MOV BX,FIELD_LENGTH
SUB BX,AX
MOV BUFFER_LEFT,BX
ADD AX,Offset SCRN_BUFR
MOV BUFFER_POSITION,AX
MOV LINE_POSITION,1
CALL MOVE_SCREEN
POP CX
RET
DELETE_LINE ENDP
DELETE_TO_EOT PROC NEAR
; Clears from the current cursor position to the end of the text buffer.
MOV CX,BUFFER_END ;recalc BUFFER_LEFT
SUB CX,BUFFER_POSITION ;now has chars left
MOV BUFFER_LEFT,CX
MOV DI,BUFFER_POSITION ;point at buffer position
MOV AL,' ' ;clear from here
REP STOSB
CALL MOVE_SCREEN ;now show the screen
POP CX
JMP GET_LINE_LOOP1
DELETE_TO_EOT ENDP
DO_BREAK PROC NEAR
POP DX ;clear stack
JMP EDIT_TXT_END_1
DO_BREAK ENDP
DO_END PROC NEAR
MOV AX,PGWIDTH ;page width - line position
CMP LINE_POSITION,AX ;end of line?
JL DO_END_1 ;no, OK to continue
JMP BAD_KEY ;yes, invalid key
DO_END_1:
MOV AX,PGWIDTH
SUB AX,LINE_POSITION ;= # of chars to move
ADD BUFFER_POSITION,AX ;bump cursor position
SUB BUFFER_LEFT,AX ;reduce no of chars left
MOV AX,PGWIDTH
MOV LINE_POSITION,AX ;set line position
MOV AX,BUFFER_END ;point at end of buffer
CMP AX,BUFFER_POSITION
JNE DO_END_2 ;not at last position
DEC BUFFER_POSITION
MOV BUFFER_LEFT,1
DEC LINE_POSITION
DO_END_2:
GCRSR ;get the cursor
MOV DL,LAST_COLUMN ;set end position
SCRSR ;display it
POP CX
RET
DO_END ENDP
; PAGE_DOWN moves to next screen. Stops with bottom of input area
; on last line.
;
DO_PAGE_DOWN PROC NEAR
CMP IN_LAST_PAGE,0
JE PG_DN_0
JMP BAD_KEY
PG_DN_0:
CALL PAGE_NUMBER ;get the current page number
MOV AX,SCROLL_PAGE
MOV BX,PAGE_SIZE
MUL BX ;AX now has offset to next page line 1
ADD AX,Offset SCRN_BUFR ;make it an offset to buffer
CMP AX,BUFFER_END ;past end?
JL PG_DN_1 ;no
SUB AX,PAGE_SIZE ;yes, point at start of last page
CMP BUFFER_POSITION,AX ;did we move down?
JL PG_DN_1 ;yes
JMP BAD_KEY
PG_DN_1:
MOV BX,BUFFER_END ;end of buffer
MOV BUFFER_POSITION,AX ;set the buffer pointer
ADD AX,PAGE_SIZE
SUB BX,AX ;chars left
JNC PG_DN_2 ;not past end
MOV AX,BUFFER_POSITION
SUB AX,PGWIDTH ;back up one line
MOV IN_LAST_PAGE,0FFH ;set flag
JMP PG_DN_1 ;and adjust
PG_DN_2:
MOV BX,BUFFER_END ;calc chars left
SUB BX,BUFFER_POSITION
MOV BUFFER_LEFT,BX
MOV LINE_POSITION,1
CALL HOME_CURSOR ;put cursor at beginning of window
CALL MOVE_SCREEN
POP CX
RET
DO_PAGE_DOWN ENDP
;
; PAGE_UP moves screen to top of preceding page
;
DO_PAGE_UP PROC NEAR
MOV AX,BUFFER_POSITION ;current buffer position
CMP AX,Offset SCRN_BUFR ;at start now?
JG PG_UP_1
PG_UP_0:
JMP BAD_KEY
PG_UP_1:
CALL PAGE_NUMBER ;get page of current buffer pointers
CMP IN_LAST_PAGE,0 ;in last page?
JE PG_UP_2 ;no
MOV IN_LAST_PAGE,0 ;yes, reset
PG_UP_2:
MOV AX,SCROLL_PAGE ;put it in AX
CMP AX,1 ;in first page?
JE PG_UP_0
SUB AX,2 ;page to be in adjsted to base 0
MUL PAGE_SIZE ;AX now has offset from start of buffer
ADD AX,Offset SCRN_BUFR ;make it actual position
MOV BUFFER_POSITION,AX ;set buffer position
SUB AX,Offset SCRN_BUFR ;calculate buffer left
MOV BX,FIELD_LENGTH
SUB BX,AX
MOV BUFFER_LEFT,BX
MOV LINE_POSITION,1
CALL HOME_CURSOR ;put cursor at beginning of window
CALL MOVE_SCREEN
POP CX
RET
DO_PAGE_UP ENDP
DO_RETURN PROC NEAR
MOV AX,BUFFER_POSITION ;calculate buffer change
SUB AX,Offset SCRN_BUFR ;from current position
XOR DX,DX
DIV PGWIDTH ;mod value in AX
INC AX ;round up to start of next line
MUL PGWIDTH
ADD AX,Offset SCRN_BUFR
SUB AX,BUFFER_POSITION ;AX has # of chars left
ADD BUFFER_POSITION,AX ;current position
MOV LINE_POSITION,1 ;set line char count
SUB BUFFER_LEFT,AX ;# of remaining chars
JG DO_RETURN_1 ;at end of input area?
MOV AX,BUFFER_END
SUB AX,PGWIDTH
MOV BUFFER_POSITION,AX
MOV LINE_POSITION,1
MOV IN_LAST_PAGE,0FFH
MOV AX,PGWIDTH
MOV BUFFER_LEFT,AX
JMP BAD_KEY ;go write file
DO_RETURN_1:
GCRSR ;get cursor location
CMP LAST_ROW,DH
JG DO_RETURN_2
CALL SCROLL_DOWN
POP CX
RET
DO_RETURN_2:
INC DH ;bump to next line
MOV DL,FIRST_COLUMN ;start of next line
SCRSR ;set cursor function
POP CX
RET
DO_RETURN ENDP
DO_TAB PROC NEAR
MOV BX,BUFFER_LEFT ;save in register
MOV REG4,BX
GCRSR ;get cursor location function
MOV AL,DL ;copy horizontal location
MOV CH,AL
ADD AL,08H ;add tab increment
AND AL,0F8H ;round down to multiple of 8
CMP AL,LAST_COLUMN ;end of line?
JL DO_TAB_0
JMP DO_RETURN ;yes, same as CR
DO_TAB_0:
XOR AH,AH
MOV HCURSOR_SAVE,AL ;save the position
SUB AL,CH ;get difference
MOV Word Ptr BUFFER_LEFT,AX ;put difference in BUFFER_LEFT
MOV BX,BUFFER_LEFT
MOV REG5,BX
MOV BX,REG4
MOV BUFFER_LEFT,BX
CMP BX,REG5
JNL DO_TAB_1
JMP DO_RETURN
DO_TAB_1:
MOV BX,REG5 ;get difference
ADD BUFFER_POSITION,BX ;bump buffer position
ADD LINE_POSITION,BX ;and line char position
SUB BUFFER_LEFT,BX ;decremant remaining chars
GCRSR ;get cursor function
MOV DL,HCURSOR_SAVE ;get horizontal position
SCRSR ;set cursor function
POP CX
RET
DO_TAB ENDP
END_SCREEN PROC NEAR
MOV AX,Offset SCRN_BUFR
ADD AX,FIELD_LENGTH
SUB AX,PAGE_SIZE
MOV BUFFER_POSITION,AX
MOV AX,PAGE_SIZE
MOV BUFFER_LEFT,AX
MOV LINE_POSITION,1
MOV IN_LAST_PAGE,0FFH
CALL HOME_CURSOR
CALL MOVE_SCREEN
POP CX
RET
END_SCREEN ENDP
HELP PROC NEAR
; Displays pre-defined Help screen. This routine does not test for max
; line and page sizes because it is purely internal to this editor and
; its input is under control of only the programmer.
MOV AH,0FH ;get video mode
INT 010H
CMP AL,07H ;is it mono?
JNE HELP_1 ;no, OK to continue
JMP BAD_KEY ;yes, beep and return
HELP_1:
GCRSR ;save cursor position on screen 0
PUSH DX
CMP HELP_SW,0 ;need to build screen?
JNE HELP_3 ;no, already done
MOV HELP_SW,0FFH ;set HELP entered flag
MOV AL,02H ;page 2 (because of line 26 indicators)
MOV AH,05H
INT 010H ;set page
MOV CH,0 ;set window @ full page
MOV CL,0
MOV DL,79
MOV DH,24
MOV BH,ATTRIBUTE
MOV AL,0
MOV AH,06H ;initialize and clear window
INT 010H
MOV BH,2 ;page
MOV DH,0 ;row for cursor screen
MOV DL,0 ;column
MOV AH,02H ;set cursor position
INT 010H
MOV CX,25*80 ;set # to scan at max
MOV SI,Offset HELP_TEXT
HELP_2:
PUSH CX ;save count
LODSB ;get the character
CMP AL,EOL ;end of message char?
JNE HELP_4 ;no, keep looping
POP CX ;yes, clear PUSH
JMP Short HELP_3 ;and exit
HELP_4:
CMP AL,CR ;is it <CR>?
JNE HELP_2A ;no
INC DH ;yes, bump line
MOV DL,1 ;and put cursor at start of row
MOV BH,02H ;page
MOV AH,02H
INT 010H
JMP Short HELP_2X ;continue loop
HELP_2A:
CMP AL,LF
JE HELP_2X
MOV CX,1 ;output the character
MOV AH,0AH
INT 010H
MOV BH,02H ;page
CMP DL,78 ;at end of line?
JLE $$0001 ;no
MOV DL,0 ;yes, set column
INC DH ;and bump row
$$0001:
INC DL ;bump column
MOV AH,02 ;set the cursor
INT 010H
HELP_2X:
POP CX ;restore the count
LOOP HELP_2 ;keep looking
HELP_3: ;executed when help screen is complete
MOV AL,2 ;switch screen to page 2
MOV AH,05H
INT 010H
MOV AH,08H ;any key clears help
INT 021H ;wait for input
CMP AL,0 ;extended char?
JNE HELP_3A ;no
INT 021H ;yes, read another to clear
HELP_3A:
MOV AL,0 ;switch back to page 0
MOV AH,05H
INT 010H
POP DX ;get input cursor position
SCRSR ;restore it
POP CX
RET
HELP ENDP
HOME_KEY PROC NEAR
; Moves cursor to beginning of current line
GCRSR ;get cursor
MOV DL,FIRST_COLUMN ;point at start
SCRSR
MOV AX,BUFFER_POSITION ;current position
SUB AX,Offset SCRN_BUFR
XOR DX,DX
MOV BX,PGWIDTH
DIV BX
MUL BX ;set to start of line
ADD AX,Offset SCRN_BUFR
MOV BUFFER_POSITION,AX ;number of chars
MOV LINE_POSITION,1 ;set back at start
MOV AX,BUFFER_END
SUB AX,BUFFER_POSITION
MOV BUFFER_LEFT,AX ;recalc remaining chars
POP CX
RET
HOME_KEY ENDP
INSERT PROC NEAR
XOR INSERT_TOGGLE,0FFH ;flip toggle
CALL SHOW_INSERT
POP CX
RET
INSERT ENDP
INSERT_LINE PROC NEAR
;
CALL FIND_LINE_NUMBER ;AX returns line number
MOV BX,PGWIDTH
MUL BX ;AX now has number of chars from start
PUSH AX
MOV CX,FIELD_LENGTH
SUB CX,AX
SUB CX,BX ;CX has chars to move
MOV DI,Offset SCRN_BUFR ;set up end of buffer
ADD DI,FIELD_LENGTH
DEC DI ;points at last character
MOV SI,DI
SUB SI,PGWIDTH ;start of move
STD ;move from end of buffer
REP MOVSB ;do the move
MOV CX,PGWIDTH
MOV AL,' ' ;fill character
REP STOSB ;fill last line
CLD ;reset
GCRSR
MOV DL,FIRST_COLUMN
SCRSR
POP AX ;get offset from start
MOV BX,FIELD_LENGTH
SUB BX,AX
MOV BUFFER_LEFT,BX
ADD AX,Offset SCRN_BUFR
MOV BUFFER_POSITION,AX
MOV LINE_POSITION,1
CALL MOVE_SCREEN
POP CX
RET
INSERT_LINE ENDP
START_SCREEN PROC NEAR
MOV AX,FIELD_LENGTH
MOV BUFFER_LEFT,AX
MOV BUFFER_POSITION,Offset SCRN_BUFR
MOV LINE_POSITION,1
MOV IN_LAST_PAGE,0
CALL HOME_CURSOR ;put cursor at beginning of window
CALL MOVE_SCREEN
POP CX
RET
START_SCREEN ENDP
SUBTTL Subroutines (CALLed Routines)
PAGE
ADVANCE_CURSOR PROC NEAR
; Advances the cursor position on the screen.
; Does not update memory pointers.
; Returns carry if SKIP_FLAG = 0 and line advances
PUSH AX
GCRSR ;get cursor location function
CMP DL,LAST_COLUMN ;end of line?
JE ADV_CRSR_1
INC DL ;bump column position on screen
JMP Short ADV_CRSR_2
ADV_CRSR_1:
CMP DH,LAST_ROW ;on last row?
JE ADV_CRSR_3 ;yes, scroll screen
MOV DL,FIRST_COLUMN
INC DH
ADV_CRSR_2:
SCRSR ;set cursor location function
CLC ;clear carry flag
JMP Short ADV_CRSR_RET
ADV_CRSR_3:
CMP SKIP_FLAG,0 ;no scroll flag set?
JNE ADV_CRSR_RET ;yes
STC ;set CY
ADV_CRSR_RET:
POP AX
RET
ADVANCE_CURSOR ENDP
BACK_CURSOR PROC NEAR
; Backs the cursor up one position. Depends on caller knowing that the
; move is OK
; Does not update memory pointers.
PUSH AX
GCRSR ;get the current position
CMP DL,FIRST_COLUMN ;is it at start?
JLE BCK_CUR_1 ;yes, move to previous line
DEC DL ;no, just reduce it
JMP Short BCK_CUR_2
BCK_CUR_1:
MOV DL,LAST_COLUMN ;end of line
DEC DH ;up one line
BCK_CUR_2:
SCRSR ;now reset it
POP AX
RET
BACK_CURSOR ENDP
BEEP PROC NEAR ;sounds alarm
MOV DL,BEL
MOV AH,06H
INT 021H
RET
BEEP ENDP
CUR_LFT PROC NEAR
; Move the cursor left on the screen and adjust memory pointers
MOV BX,Offset SCRN_BUFR ;check for start of data
CMP BX,BUFFER_POSITION ;at beginning?
JNL CUR_LFT_BAD ;yes, set error indication
DEC BUFFER_POSITION ;no, set position back one
INC BUFFER_LEFT ;bump remaining characters
CMP LINE_POSITION,1 ;at line start?
JNE CUR_LFT_1
MOV BX,PGWIDTH
MOV LINE_POSITION,BX ;yes, set new line at end
JMP Short CUR_LFT_2
CUR_LFT_1:
DEC LINE_POSITION ;keep line char count
CUR_LFT_2:
CALL BACK_CURSOR ;set cursor position on screen
CLC ;clear error
RET
CUR_LFT_BAD:
STC ;set carry
RET
CUR_LFT ENDP
FIND_LINE_NUMBER PROC NEAR
; Returns current line number in AX (starts at 0)
PUSH DX
PUSH BX
MOV AX,BUFFER_POSITION
SUB AX,Offset SCRN_BUFR
MOV BX,PGWIDTH
XOR DX,DX
DIV BX
POP BX
POP DX
CLC
RET
FIND_LINE_NUMBER ENDP
HOME_CURSOR PROC NEAR
GCRSR
MOV DL,FIRST_COLUMN
MOV DH,FIRST_ROW
SCRSR
RET
HOME_CURSOR ENDP
MOVE_SCREEN PROC NEAR
; Moves data from buffer pointed to by BUFFER_POSITION to current cursor position
; for length of screen
GCRSR ;get cursor function
PUSH DX
MOV BX,PGWIDTH
XOR AX,AX ;clear
MOV AL,LAST_ROW ;calculate total screen space
SUB AL,FIRST_ROW
INC AX
MUL BX ;AX now has total
POP DX ;restore DX
PUSH AX ;save total
PUSH DX ;hold it again
XOR AX,AX
MOV AL,DH ;get current row
SUB AL,FIRST_ROW ;calculate space used
MUL BX
POP DX ;restore original position
ADD AL,DL ;add current offset
ADC AH,0 ;take care of carry
SUB AX,FIRST_COL_WORD ;get rid of unused columns
NEG AX
POP CX ;get total space (PUSHed from AX)
ADD CX,AX ;calculate size to move
PUSH SKIP_FLAG ;save current setting
MOV SKIP_FLAG,1 ;no scroll at end of screen
PUSH DX ;save cursor position
MOV SI,BUFFER_POSITION ;initialize pointer for display char
MOVE_SCRN_LOOP:
LODSB ;put character in AL
WCRSR
CALL ADVANCE_CURSOR
LOOP MOVE_SCRN_LOOP
POP DX
POP SKIP_FLAG ;restore
SCRSR ;reposition
RET
MOVE_SCREEN ENDP
PAGE_NUMBER PROC NEAR
; Finds the page number associated with the current buffer position pointers
; Returns it in word field SCROLL_PAGE
PUSH AX ;save registers used
PUSH BX
PUSH CX
PUSH DX
MOV SCROLL_PAGE,0 ;initialize
MOV AX,FIELD_LENGTH ;calculate number to loop
XOR DX,DX
DIV PAGE_SIZE
MOV CX,AX ;CX has max number of pages
INC CX
MOV BX,CX ;save max pages
MOV AX,Offset SCRN_BUFR
CMP IN_LAST_PAGE,0 ;now in last page?
JE PG_NUM_1 ;no
MOV SCROLL_PAGE,CX
STC ;let us know how we got last page
JMP Short PG_NUM_RET
PG_NUM_1:
INC SCROLL_PAGE ;bump page number
ADD AX,PAGE_SIZE ;bump next page start
CMP AX,BUFFER_POSITION ;is it in here?
JG PG_NUM_2
LOOP PG_NUM_1
DEC SCROLL_PAGE ;went past end, set back
STC ;shouldn't drop through
JMP Short PG_NUM_RET
PG_NUM_2:
CLC ;page OK
PG_NUM_RET:
POP DX ;restore registers used
POP CX
POP BX
POP AX
RET
PAGE_NUMBER ENDP
SCROLL_DOWN PROC NEAR
; Scrolls the screen down one line
PUSH SI
PUSH DX
PUSH CX
PUSH BX
PUSH AX
XOR BX,BX ;clear
MOV BH,ATTRIBUTE ;attribute to fill with
MOV AH,06H ;scroll window up function
MOV AL,01H ;scroll 1 line
MOV CH,FIRST_ROW
MOV CL,FIRST_COLUMN
MOV DH,LAST_ROW
MOV DL,LAST_COLUMN
INT 010H
MOV BX,LINE_POSITION ;calculate cursor offset
ADD BL,FIRST_COLUMN ;from current line offset
DEC BX ;screen position is base 0
MOV DL,BL
MOV DH,LAST_ROW
SCRSR
MOV SI,BUFFER_POSITION ;offset of data
SUB SI,LINE_POSITION
INC SI ;account for base 0
MOV CX,PGWIDTH ;amount to move
XOR BX,BX ;clear
GCRSR
MOV REG8,DX ;save current position
MOV DL,FIRST_COLUMN ;point at start of line
SCRSR ;put cursor there
SCRL_DN_1:
PUSH CX
MOV CX,1
LODSB
WCRSR ;display char function
INC DL
SCRSR
POP CX
LOOP SCRL_DN_1
MOV DX,REG8 ;get cursor position
SCRSR ;restore it
POP AX
POP BX
POP CX
POP DX
POP SI
RET
SCROLL_DOWN ENDP
SET_LAST_LINE PROC NEAR
; Allows entry on last line after an error
MOV AX,FIELD_LENGTH ;get no of characters
ADD AX,Offset SCRN_BUFR ;end of characters
DEC AX
MOV BUFFER_POSITION,AX ;set buffer position
MOV AX,PGWIDTH ;set line position
DEC AX ;at end
MOV LINE_POSITION,AX
MOV BUFFER_LEFT,1 ;set number of chars
GCRSR ;get cursor position
MOV DL,LAST_COLUMN ;position column
MOV DH,LAST_ROW
SCRSR ;move cursor to end of window
RET
SET_LAST_LINE ENDP
DO_ESCAPE:
JMP BAD_KEY
CNVT_DEC PROC NEAR
; Converts an ASCIIZ numeric string in the field ARGUMENT
; to a hex value in AX
MOV BP,0 ;set index
XOR AX,AX ;clear result
MOV BX,10 ;base
XOR CX,CX
CNVT_DEC_LOOP:
MOV AL,Byte Ptr ARGUMENT[BP]
CMP AL,0 ;end of number?
JE CNVT_DEC_RET ;yes
CMP AL,' ' ;no, is it blank?
JE CNVT_DEC_LOOP2 ;yes, keep searching for data
SUB AL,'0' ;no, convert to binary
PUSH AX ;save digit
MOV AX,CX ;get current sum
MUL BX ;multiply by 10
MOV CX,AX ;put result in total
POP AX ;get new digit
ADD CX,AX ;add in to low order
XOR AX,AX ;clear
CNVT_DEC_LOOP2:
INC BP ;bump to next digit
JMP CNVT_DEC_LOOP ;go process
CNVT_DEC_RET:
RET ;back to caller
CNVT_DEC ENDP
SHOW_INSERT PROC NEAR
; Shows the current status of the INS key
PUSH ES
MOV AX,0B800H ;in general case could be 0B000H
MOV ES,AX
CMP INSERT_TOGGLE,0 ;insert off?
JNE SHO_INS_2 ;no, must be on
MOV SI,Offset THREE_BLANKS
JMP Short SHO_INS_3
SHO_INS_2:
MOV SI,Offset INS_STRING
SHO_INS_3:
MOV DI,80 ;offset of INS char in buffer
MOV CX,3
SHO_INS_4:
MOVSB
INC DI ;bump past attribute
LOOP SHO_INS_4
POP ES ;restore
RET
SHOW_INSERT ENDP
SCRN_BUFR DB MAXLEN DUP(' ')
SCRN_BUFR_END:
DB 100 dup (?) ;extra space for safety's sake
DBASEDIT ENDP
CSEG ENDS
END